TCK tests for async invokers#706
Conversation
|
Draft because the TCK audit already contains changes from jakartaee/cdi#961. Otherwise this is ready for review and then merge. |
|
Rebased. Since jakartaee/cdi#961 was merged, this is ready for review. |
manovotn
left a comment
There was a problem hiding this comment.
We should also add a test for AfterDeploymentValidation.ensureAsyncHandlerExists()
If anything, we should add a copy of this PR for Portable Extensions. I don't see the need to add a test for this one method, without testing the rest of the infrastructure through PEs. |
That would be even better for sure :) |
|
@Ladicek do you want to address the PE counterpart in this PR should we open a new one? |
|
To be honest, I'd love someone else to do the PE part 😆 |
I have added a PE variant of the three positive test cases - is that OK with you @Ladicek? |
|
Just about perfect, thanks! |
|
Added a 2nd commit that contains TCK tests for the respecified async handlers (jakartaee/cdi#967). Before merging, the commits should be squashed. Asked for a new review. |
|
@manovotn I think I screwed up by force-pushing the new TCK, because that dropped your commit with PEs tests. Do you by any chance still have them locally? Thanks! :-) |
|
Squashed and rebased. @manovotn could you please take a look if you still have your PE tests locally? Sorry I dropped them. |
Pushed |
manovotn
left a comment
There was a problem hiding this comment.
I went over the tests as I was implementing it in Weld and it LGTM 👍
|
Yeah, I will take a look |
Azquelt
left a comment
There was a problem hiding this comment.
I noticed that some of the spec assertions are out of date and need fixed.
I also realised that with a parameter async handler the dependent beans may be destroyed before the method returns and I'm not sure if that's the behaviour we want (though that's a spec issue, not really related to these tests)
|
|
||
| @Test | ||
| @SpecAssertion(section = Sections.USING_INVOKER_BUILDER_FULL, id = "a") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "ja") |
|
|
||
| @Test | ||
| @SpecAssertion(section = Sections.USING_INVOKER_BUILDER_FULL, id = "a") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "jb") |
|
|
||
| @Test | ||
| @SpecAssertion(section = Sections.USING_INVOKER_BUILDER_FULL, id = "a") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "jc") |
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "b") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "g") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "h") |
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "b") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "i") | ||
| public void testSyncThrow() { |
There was a problem hiding this comment.
ha (synchronous completion) appears not to be tested in PE and neither is the transformReturnValue method.
There was a problem hiding this comment.
cfandhc?
cf, hc, k actually
ha(synchronous completion) appears not to be tested in PE
Correct. I'm adding a test, because there's one for BCE.
and neither is the
transformReturnValuemethod.
Need to take a look at this.
There was a problem hiding this comment.
and neither is the
transformReturnValuemethod.Need to take a look at this.
This is actually more widespread: we don't have any test that would check transformReturnValue(). I'll try to add one (or two, actually -- for BCE and PE).
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "b") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "g") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "h") | ||
| public void test() throws Exception { |
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "b") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "i") | ||
| public void testSyncThrow() { |
There was a problem hiding this comment.
A test for synchronous successful completion is missing here too, and I'm also adding it.
| @Test(dataProvider = ARQUILLIAN_DATA_PROVIDER) | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "cf") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "ha") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "i") | ||
| @SpecAssertion(section = Sections.INVOKER_ASYNCHRONOUS_METHODS, id = "j") | ||
| public void testSync(InvokerHolder invokers) throws Exception { | ||
| MyDependentBean.reset(); | ||
|
|
||
| Invoker<MyBean, MyAsyncType<String>> hello = invokers.get("helloSync"); | ||
| MyAsyncType<String> result = MyAsyncType.createSuspended(); | ||
|
|
||
| assertEquals(MyDependentBean.destroyedCounter.get(), 0); | ||
|
|
||
| hello.invoke(null, new Object[] { null, result }); | ||
|
|
||
| assertEquals(MyDependentBean.destroyedCounter.get(), 1); | ||
| assertTrue(result.isComplete()); | ||
| assertEquals(result.getIfComplete(), "hello"); | ||
| } |
There was a problem hiding this comment.
In this test we don't assert whether the dependent beans are destroyed before or after the method returns.
I think that, as currently specified, the beans should be destroyed as soon as async.resume is called inside the helloSync method, i.e. before the method returns, which is a little odd given that you could be destroying the bean that you called the method on and it's a bit difficult for the async handler to avoid that.
As the spec is currently written, I think this test is correct but we might want to consider deferring destruction until both complete is called and the method returns.
There was a problem hiding this comment.
Very good observation! Let me think about that for a bit.
There was a problem hiding this comment.
I think I addressed all comments except of this one. It is a little tricky.
Currently, the specification indeed requires that completion is signaled and hence CC is released before the method returns. This would be especially wrong if the target bean is @Dependent and its instance is looked up by the invoker.
I tried fixing the issue locally and there seems to be a relatively straightforward way, so I'll look at:
- specifying that the CC is released after the method returns, even if completion was signaled before the method returned,
- modifying the TCK.
Hopefully tomorrow.
There was a problem hiding this comment.
Submitted a spec clarification: jakartaee/cdi#973
Will submit fixed tests to this PR later today.
There was a problem hiding this comment.
Added one commit with a test. Turns out it's just one assert in an existing test, which seems nice :-)
A "two-way" async type signals completion through two different ways: - synchronous completion is signalled through the method's return value - asynchronous completion is signalled through the async parameter and the return value is a dummy placeholder This occurs in practice with Kotlin `suspend` functions, where if the function completes synchronously, it returns the value directly, and if it completes asynchronously, it signals completion through a parameter (and the return value is a placeholder). The tests in this commit are of course not written in Kotlin, but they are structured in the same way.
These tests ignore the return values of invokers, so the wrong return type has not been an issue. It is still wrong, though, and should be fixed.
|
Rebased and added 3 commits:
|
…arget method is still running
|
This PR now includes a test of jakartaee/cdi#973 |
|
I intend to squash the commits here before merging, but will leave the PR in its current state for easier review. |
Fixes #698